package TestCase;

import com.beanit.iec61850bean.ClientAssociation;
import com.beanit.iec61850bean.ClientEventListener;
import com.beanit.iec61850bean.ClientSap;
import com.beanit.iec61850bean.Report;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import util.CheckUtil;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class AssociatedServicesTestCase implements ClientEventListener {
    private static final Logger logger = LoggerFactory.getLogger("IEC61850-Client");


    private CheckUtil checkUtil = new CheckUtil();

    public   ClientAssociation OpenAssociation(InetAddress address){
        ClientAssociation clientAssociation = null;
        ClientSap clientSap = new ClientSap();
        try {
            clientAssociation = clientSap.associate(address, 102, null, this);
        } catch (IOException e) {
            logger.error("Unable to connect to remote host.");
            return null;
        }
        return  clientAssociation;
    }

    public boolean AssociationsWereEstablishedAndReleased_250_timesTest(String host){
        InetAddress address  = checkUtil.hostCheck(host);
        if(address==null){
            logger.error("Associations were established and released 250 times test -------------FAIL");
            return false;
        }
        logger.info("Associations were established and released 250 times test started!");
        for (int i = 0; i < 250; i++){
            int times = i + 1;
            logger.debug("Establishing and releasing associations test " + times + " times");
            ClientAssociation clientAssociation = OpenAssociation(address);
            if (clientAssociation == null){
                logger.error("Associations were established and released 250 times test -------------FAIL");
                return false;
            }
            clientAssociation.disconnect();
            clientAssociation.close();
            while (clientAssociation.isOpen()){
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    //e.printStackTrace();
                }
            }
        }
        logger.debug("Associations were established and released 250 times test -------------PASS");
        return true;
    }

    public boolean AssociationsWereEstablishedAndAbort_250_timesTest(String host){
        InetAddress address  = checkUtil.hostCheck(host);
        if(address==null){
            logger.error("Associations were established and abort 250 times test -------------Fail");
            return false;
        }
        logger.info("Associations were established and abort 250 times test Started!");
        for (int i = 0; i < 250; i++){
            int times = i + 1;
            logger.debug("Establish and abort association test test " + times + " times");
            ClientAssociation clientAssociation = OpenAssociation(address);
            if (clientAssociation == null){
                logger.error("Associations were established and abort 250 times test -------------Fail");
                return false;
            }

            clientAssociation.close();
            while (clientAssociation.isOpen()){
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    //e.printStackTrace();
                }
            }

        }
        logger.debug("Associations were established and abort 250 times test -------------PASS");
        return true;
    }


    public boolean MaxClientTest(String host){
        InetAddress address  = checkUtil.hostCheck(host);
        if(address==null){
            logger.error("Maximum sixteen client test -------------FAIL");
            return false;
        }
        logger.info("Maximum sixteen client test started!");
        ArrayList<ClientAssociation> clientAssociationList = new ArrayList<>();
        int successCount = 0;
        int failCount = 0;
        for (int i = 0 ; i< 17; i++){
            ClientAssociation clientAssociation = OpenAssociation(address);
            if (clientAssociation!=null){
                clientAssociationList.add(successCount, clientAssociation);
                successCount = successCount + 1;
                String message = successCount + "  clients have been successfully connected";
                logger.info(message);
            }else {
                failCount = failCount + 1;
            }
        }
        if (successCount!=16||failCount!=1){
            logger.error("Maximum sixteen client test -------------FAIL");
            for (ClientAssociation item:clientAssociationList
            ) {
                item.disconnect();
            }
            for (ClientAssociation item:clientAssociationList
            ) {
                item.close();
            }
            return false;
        }
        for (ClientAssociation item:clientAssociationList
             ) {
            item.disconnect();
        }
        for (ClientAssociation item:clientAssociationList
             ) {
            item.close();
        }
        logger.debug("Maximum sixteen client test -------------PASS");
        return true;
    }

    @Override
    public void newReport(Report report) {

    }

    @Override
    public void associationClosed(IOException e) {

    }
}
